using System.Text.RegularExpressions;

namespace Test.ConsoleProgram.Algorithm.SwordFingerOffer
{
    [TestDescription("剑指 Offer 0020. 表示数值的字符串")]
    public class No0020_IsNumber : AbsBaseTestItem
    {
        /*
        请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。
        例如，字符串"+100"、"5e2"、"-123"、"3.1416"、"-1E-16"、"0123"都表示数值
        但"12e"、"1a3.14"、"1.2.3"、"+-5"及"12e+5.4"都不是。
        */

        public override void OnTest()
        {
            // 正则
            Assert.TestExe(IsNumber, "+100", true);
            Assert.TestExe(IsNumber, "5e2", true);
            Assert.TestExe(IsNumber, "-123", true);
            Assert.TestExe(IsNumber, "3.1416", true);
            Assert.TestExe(IsNumber, "-1E-16", true);
            Assert.TestExe(IsNumber, "0123", true);

            Assert.TestExe(IsNumber, "12e", false);
            Assert.TestExe(IsNumber, "1a3.14", false);
            Assert.TestExe(IsNumber, "1.2.3", false);
            Assert.TestExe(IsNumber, "+-5", false);
            Assert.TestExe(IsNumber, "12e+5.4", false);

            // 大神
            Assert.TestExe(IsNumber_2, "+100", true);
            Assert.TestExe(IsNumber_2, "5e2", true);
            Assert.TestExe(IsNumber_2, "-123", true);
            Assert.TestExe(IsNumber_2, "3.1416", true);
            Assert.TestExe(IsNumber_2, "-1E-16", true);
            Assert.TestExe(IsNumber_2, "0123", true);

            Assert.TestExe(IsNumber_2, "12e", false);
            Assert.TestExe(IsNumber_2, "1a3.14", false);
            Assert.TestExe(IsNumber_2, "1.2.3", false);
            Assert.TestExe(IsNumber_2, "+-5", false);
            Assert.TestExe(IsNumber_2, "12e+5.4", false);
        }

        /// <summary>
        /// 正则表达式
        /// </summary>
        public bool IsNumber(string s)
        {
            if (string.IsNullOrWhiteSpace(s))
                return false;
            var regex = new System.Text.RegularExpressions.Regex(@"^\s*(-|\+)?(\d+|\d+\.\d*|\d*\.\d+)(E(-|\+)?\d+)?\s*$",
                System.Text.RegularExpressions.RegexOptions.IgnoreCase |
                System.Text.RegularExpressions.RegexOptions.Singleline |
                System.Text.RegularExpressions.RegexOptions.Compiled);
            return regex.IsMatch(s);
        }

        /// <summary>
        /// 大神解法
        /// </summary>
        public bool IsNumber_2(string s)
        {
            if (s == null || s.Length == 0)
            {
                return false;
            }
            s = s.Trim();
            bool numflag = false;
            bool dotflag = false;
            bool eflag = false;
            for (int i = 0; i < s.Length; i++)
            {
                if (s[i] >= '0' && s[i] <= '9')
                {
                    numflag = true;
                }
                else if (s[i] == '.' && !dotflag && !eflag)
                {
                    dotflag = true;
                }
                else if ((s[i] == 'e' || s[i] == 'E') && !eflag && numflag)
                {
                    eflag = true;
                    numflag = false;
                }
                else if ((s[i] == '+' || s[i] == '-') && (i == 0 || s[i - 1] == 'e' || s[i - 1] == 'E'))
                {
                }
                else
                {
                    return false;
                }
            }
            return numflag;
        }
    }
}
